package com.yonyou.pmclouds.workflow.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.entity.PageObject;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.YhtSdkProperties;
import com.yonyou.pmclouds.billtype.entity.BillTypeVO;
import com.yonyou.pmclouds.workflow.entity.ProcessDataSynVO;
import com.yonyou.pmclouds.workflow.entity.ProcessDefinitionVO;
import com.yonyou.pmclouds.workflow.service.rmiitf.ProcessDefinitionService;
import com.yonyou.yht.sdk.UserCenter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.List;

import static com.yonyou.pmclouds.basecom.PMControllerConst.DEFAULT_PAGE_PAGE_START;
import static com.yonyou.pmclouds.basecom.PMControllerConst.DEFAULT_PAGE_SIZE;

@RestController
@RequestMapping("/processDefinition")
public class ProcessDefinitionController {

    @Reference(version = ApplicationConsts.APPLICATION_VERSION)
    private ProcessDefinitionService definitionService;

    private static final String TOKEN = "token";

    @RequestMapping("/insert")
    @ResponseBody
    public Object insertProcessDefinition(@Valid @RequestBody ProcessDefinitionVO definitionVO, BindingResult bindingResult)
            throws BusinessException {
        this.validArgs(bindingResult);

        return definitionService.insertProcessDefinitionModel(definitionVO);
    }

    @RequestMapping("/changeProcessStatus")
    @ResponseBody
    public Object updateProcessStatus(@RequestBody ProcessDefinitionVO definitionVO) throws BusinessException {
//         现在停用和启用没有控制云审批的流程状态，停用也不影响流程实例审批，暂时不加校验
//        if(ProcessDefinitionVO.PROCESS_STATUS_STOP.equalsIgnoreCase(definitionVO.getProcessStatus())) {
//            // 停用时校验该流程是否存在运行中的实例，存在不可停用
//            ProcessExecuteAction executeAction = new ProcessExecuteAction(definitionVO.getUserId(), definitionVO.getPkTenant(), processService1);
//            JsonNode instancesNode = executeAction.getInstances(definitionVO.getProcessKey());
//            if(instancesNode.get(ProcessService1.FIELD_SIZE).intValue() > 0) {
//                throw new BusinessException("该单据中存在运行中的流程，不能停用");
//            }
//        }
//
        return definitionService.updateProcessStatus(definitionVO);
    }

    @RequestMapping("/list")
    @ResponseBody
    public PageObject<ProcessDefinitionVO> getDefinitionByTenantId(@RequestParam("tenantId") String tenantId,
                                                                   @RequestParam(name = "pageStart", required = false, defaultValue = DEFAULT_PAGE_PAGE_START) String pageStart,
                                                                   @RequestParam(name = "pageSize", required = false, defaultValue = DEFAULT_PAGE_SIZE) String pageSize,
                                                                   @RequestParam(name = "billType", required = false) String billType,
                                                                   @RequestParam(name = "pkOrg", required = false) String pkOrg)
            throws BusinessException {
        return definitionService.queryProcessDefinition(tenantId, billType, Integer.valueOf(pageStart), Integer.valueOf(pageSize), pkOrg);
    }

    @RequestMapping("/delete")
    @ResponseBody
    public ProcessDefinitionVO deleteDefinition(@Valid @RequestBody ProcessDefinitionVO definitionVO,
                                                BindingResult bindingResult) throws BusinessException {
        this.validArgs(bindingResult);
        if (ProcessDefinitionVO.PROCESS_STATUS_START.equalsIgnoreCase(definitionVO.getProcessStatus())) {
            throw new BusinessException("启用的审批流不允许删除");
        }

        // 将本地数据库流程定义至于删除状态
        definitionService.deleteDefinition(definitionVO);

        return definitionVO;
    }

    @RequestMapping("/update")
    @ResponseBody
    public ProcessDefinitionVO updateDefinition(@Valid @RequestBody ProcessDefinitionVO definitionVO,
                                                BindingResult bindingResult) throws BusinessException {
        this.validArgs(bindingResult);

        // 更新流程定义信息至数据库
        return definitionService.updateDefinition(definitionVO);
    }

    @RequestMapping("/queryBillType")
    @ResponseBody
    public BillTypeVO[] queryBillType(@RequestParam("tenantId") String tenantId) throws BusinessException {
        return definitionService.queryBillType(tenantId);
    }

    private void validArgs(BindingResult bindingResult) throws BusinessException {
        if (bindingResult.hasErrors()) {
            List<ObjectError> errorList = bindingResult.getAllErrors();
            StringBuilder errorBuilder = new StringBuilder();
            for (ObjectError error : errorList) {
                errorBuilder.append(error.getDefaultMessage()).append(" ");
            }
            throw new BusinessException(errorBuilder.toString());
        }
    }

    @RequestMapping("/checkIsBaseDataSyn")
    @ResponseBody
    public ProcessDataSynVO checkIsBaseDataSyn(@RequestParam("tenantId") String tenantId) throws BusinessException {
        return definitionService.checkIsBaseDataSyn(tenantId);
    }

    @RequestMapping("/getDesignerUrl")
    public String getDesignerUrl(@RequestBody ProcessDefinitionVO definitionVO, HttpServletRequest request) {
        String token = "";
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie c : cookies) {
                if (c.getName().equals(TOKEN)) {
                    token = c.getValue();
                    break;
                }
            }
        }
        String userId = definitionVO.getUserId();
        String userInfo = UserCenter.getUserById(userId);
        JSONObject jsonObject = JSONObject.parseObject(userInfo);
        String userCode = jsonObject.getJSONObject("user").getString("userCode");
        String sysId = StringUtils.isEmpty(YhtSdkProperties.getSysId()) ?
                ApplicationConsts.APPLICATION_ID : YhtSdkProperties.getSysId();
        return definitionService.getDesignerUrl() + "?modelId=" + definitionVO.getProcessId() + "&organizationId="
                + definitionVO.getPkTenant() + "&page=flow&usercode=" + userCode + "&userid=" + userId + "&token="
                + token + "&appsource=" + ApplicationConsts.APPLICATION_ID + "&source=" + ApplicationConsts.APPLICATION_ID;
    }

}
